import json
import os

import cv2
import pandas as pd

import utils.fsutils as fsutils


def boxes_to_table(boxes, shape):
    specified_rows_count = 13
    height, width, channel = shape
    boxes_copy = sorted(boxes, key=lambda x: x[2])
    rows = []
    while True:
        box_counts_per_pixel = []
        for i in range(height):
            box_count = 0
            for j in range(len(boxes_copy)):
                box = boxes_copy[j]
                if i >= box[2] and i <= box[2] + box[4]:
                    try:
                        boxnum = float(box[0])
                        if boxnum > 0:
                            box_count += 1
                    except ValueError:
                        continue
            box_counts_per_pixel.append(box_count)

        box_index_and_counts = [(i, box_counts_per_pixel[i]) for i in range(len(box_counts_per_pixel))]
        top_box_index_and_count = max(box_index_and_counts, key=lambda x: x[1])

        raw_row = []
        i = top_box_index_and_count[0]
        for j in range(len(boxes_copy)):
            box = boxes_copy[j]
            if i >= box[2] and i <= box[2] + box[4]:
                box[0] = box[0].strip()
                raw_row.append(box)
        if len(raw_row) <= 3:
            break
        row = [[None] for x in range(specified_rows_count)]
        for box in raw_row:
            index = int(box[1] * specified_rows_count / (width + 1))
            if row[index][0] is None:
                row[index] = box
            else:
                row[index][0] = row[index][0] + "" + box[0]

        rows.append((top_box_index_and_count[0], row))
        boxes_copy = [box for box in boxes_copy if box not in raw_row]

    rows = sorted(rows, key=lambda x: x[0])

    text_rows = []
    for index, row in rows:
        newrow = [box[0] for box in row]
        text_rows.append(newrow)
        # print(newrow)

    return text_rows


def save_rows(rows, filepath):
    df = pd.DataFrame(rows)
    output_path = os.path.dirname(filepath)
    if not os.path.exists(output_path):
        os.makedirs(output_path)
    df.to_csv(filepath, index=False, header=False)


def w03_boxes_to_csv(boxespath):
    # 从完整的json文件路径中提取文件名（包括后缀）
    boxes_filename = os.path.basename(boxespath)

    # 移除文件名中的".json"后缀，以得到原始图像文件名
    image_filename = boxes_filename.replace(".json", "")

    # 构建原始图像文件的完整路径。这里假设原始图像存储在特定缓存目录下
    imagepath = os.path.join(fsutils.get_cache_path_for_category("4kx3k"), image_filename)

    # 构建输出CSV文件的完整路径。这里假设CSV文件应该存储在指定的输出目录下
    csvpath = os.path.join(fsutils.get_output_csv_path(), image_filename + '.csv')

    # 检查CSV文件是否已经存在，如果存在，则打印信息并跳过处理
    if os.path.exists(csvpath):
        print("{} 已经存在，跳过".format(csvpath))
        return

    # 使用OpenCV读取图像文件
    table_image = cv2.imread(imagepath)

    # 加载json文件，这里假设json文件包含了某种形式的盒子（可能是文字区域）信息
    boxes = json.load(open(boxespath))

    # 将盒子信息和图像尺寸转换为表格行数据。这里假设`boxes_to_table`是一个自定义函数，
    # 它根据盒子信息和图像尺寸来生成表格行数据
    result_rows = boxes_to_table(boxes, table_image.shape)

    # 保存表格行数据到CSV文件。这里假设`save_rows`是一个自定义函数，
    # 它负责将表格行数据写入到CSV文件中
    save_rows(result_rows, csvpath)
